package com.chinarelife.cret;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.crypto.engines.DESedeEngine;
import org.bouncycastle.crypto.engines.RC2Engine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.pkcs.PKCS12PfxPdu;
import org.bouncycastle.pkcs.PKCS12PfxPduBuilder;
import org.bouncycastle.pkcs.PKCS12SafeBag;
import org.bouncycastle.pkcs.PKCS12SafeBagBuilder;
import org.bouncycastle.pkcs.PKCSException;
import org.bouncycastle.pkcs.bc.BcPKCS12MacCalculatorBuilder;
import org.bouncycastle.pkcs.bc.BcPKCS12PBEOutputEncryptorBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS12SafeBagBuilder;

public class SM2PfxMaker
{
  public PKCS12PfxPdu makePfx(PrivateKey privKey, PublicKey pubKey, X509Certificate[] chain, String passwd)
    throws NoSuchAlgorithmException, IOException, PKCSException
  {
    JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
    
    PKCS12SafeBagBuilder taCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[2]);
    taCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Primary Certificate"));
    

    PKCS12SafeBagBuilder caCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[1]);
    caCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("Intermediate Certificate"));
    

    PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[0]);
    eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("User Key"));
    
    eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, extUtils
      .createSubjectKeyIdentifier(pubKey));
    
    char[] passwdChars = passwd.toCharArray();
    


    PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, new BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, new CBCBlockCipher(new DESedeEngine())).build(passwdChars));
    keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("User Key"));
    
    keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, extUtils
      .createSubjectKeyIdentifier(pubKey));
    
    PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder();
    PKCS12SafeBag[] certs = new PKCS12SafeBag[3];
    certs[0] = eeCertBagBuilder.build();
    certs[1] = caCertBagBuilder.build();
    certs[2] = taCertBagBuilder.build();
    pfxPduBuilder.addEncryptedData(new BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, new CBCBlockCipher(new RC2Engine()))
    
      .build(passwdChars), certs);
    
    pfxPduBuilder.addData(keyBagBuilder.build());
    return pfxPduBuilder.build(new BcPKCS12MacCalculatorBuilder(), passwdChars);
  }
  
  public PKCS12PfxPdu makePfx(PrivateKey privKey, PublicKey pubKey, X509Certificate cert, String passwd)
    throws NoSuchAlgorithmException, IOException, PKCSException
  {
    JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
    
    PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(cert);
    eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("User Key"));
    
    eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, extUtils
      .createSubjectKeyIdentifier(pubKey));
    
    char[] passwdChars = passwd.toCharArray();
    


    PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, new BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, new CBCBlockCipher(new DESedeEngine())).build(passwdChars));
    keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString("User Key"));
    
    keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, extUtils
      .createSubjectKeyIdentifier(pubKey));
    
    PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder();
    PKCS12SafeBag[] certs = new PKCS12SafeBag[1];
    certs[0] = eeCertBagBuilder.build();
    pfxPduBuilder.addEncryptedData(new BcPKCS12PBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, new CBCBlockCipher(new RC2Engine()))
    
      .build(passwdChars), certs);
    
    pfxPduBuilder.addData(keyBagBuilder.build());
    return pfxPduBuilder.build(new BcPKCS12MacCalculatorBuilder(), passwdChars);
  }
}
